knitr::opts_chunk$set(echo=TRUE,eval=TRUE, message=FALSE, warning=FALSE)

Load packages:

library(readxl)
library(foreign)
library(haven)
library(magrittr)
library(dplyr)
library(ggplot2)    
library(plotly)
library(ggmap)
library(ggthemes)
library(ggpubr)
library(tidyverse)
library(rgdal)
library(osmdata)
library(nominatim)
library(jsonlite)
library(RColorBrewer)
library(DT)
library(tidyr)
library(leaflet)
library(formattable)
library(tigris)
library(htmlwidgets)
library(sf)
library(gganimate)
library(webshot)
library(maptools)
library(rgeos)
library(rgdal)

The relationship of in person voting VS mail-in voting and Covid-19 case development

We want to explore the relationship of in person voting VS mail-in voting and Covid-19 case development.

Part 1

Firstly, we argue that the overall pandemic situation before the voting period starts might lead to people’s preference of mail-in voting. This could be somewhat proved by the fact that people who are absence of in person voting could register for mail ballot and fill in “Covid” as the excuse.

To understand this, a graph of the change in mail-in voting preference from 2016 election to 2020 election could be drafted. Specifically, the background knowledge suggests that Trump administration and its supporters oppose mail-in voting, so we’ll also be looking at the difference of mail-in voting preference change from 2016 election to 2020 election for Democrats and Republicans respectively.

Read in information on the percentage of mail-in voting as well as the proportion of people of different parties within each state. Specifically, data chosen from SPAE is top-line statistics from nationwide study, by state, weighted data.

Data Source: Stewart, Charles, 2021, “2020 Survey of the Performance of American Elections”, https://doi.org/10.7910/DVN/FSGX7Z, Harvard Dataverse, V1, UNF:6:70KW4uouuTDT860MiPJq3A== [fileUNF]

vote<-read.csv("/Users/annie/Documents/GitHub/Group_H_Election_Covid/Peishan_Li/weightedvote.csv")
pid3<-read.csv("/Users/annie/Documents/GitHub/Group_H_Election_Covid/Peishan_Li/pid3.csv")
bystate<-inner_join(vote, pid3, by='id')
bystate<-rename(bystate, c("state"="id"))
bystate<-rename(bystate, c("mail"="Voted.by.mail.or.absentee.ballot.by.mail..including.dropping.off.a.ballot.that.was.mailed.to.you."))
bystate<-bystate %>%
  select(state, mail, Democrat, Republican) %>%
  mutate(DandR=Democrat+Republican) %>%
  mutate(Democratpercent=percent(Democrat/DandR))%>%
  mutate(Republicanpercent=percent(Republican/DandR))
bystate$mail<-percent(bystate$mail/100)
#Prepare color information for further plotting
for (i in 1:51){
  if (bystate$Democrat[i]<bystate$Republican[i]){
    bystate$party[i]="red"
  }else if (bystate$Democrat[i]>bystate$Republican[i]){
    bystate$party[i]="blue"
  }else if (bystate$Democrat[i]==bystate$Republican[i]){
    bystate$party[i]="#b2aeae"
  }
}
bystate

In the meantime, according to past final reports from SPAE also available from the link above, the mail-in voting percentage of each past election at country level could be summarized as:

overallmailpercentage<-data.frame(Year=c(2000, 2004, 2008, 2012, 2016, 2020), Percentage=c(percent(0.10), percent(0.13), percent(0.16), percent(0.19), percent(0.21), percent(0.46)))
overallmailpercentage

Percentage of mail-in voting in each election

overall<-overallmailpercentage %>%
  ggplot(.,aes(x=Year,y=Percentage))+
  theme_bw()+
  geom_line(color="lightsteelblue2")+
  geom_point(aes(size=Percentage), color="coral")+
  labs(x="Year of Election", y="Percentage of Mail-in Voting", title="Percentage of Mail-in Voting in Each Election")+
  scale_size_continuous(guide=FALSE)+
  scale_x_discrete(limits=c(2000, 2004, 2008, 2012, 2016, 2020))+
  theme(plot.title=element_text(hjust = 0.5))
overall

The graphs display a general sharp increase in mail-in voting percentage from 2016 to 2020, which could well be due to the Covid-19 development.

vote2020<-read_sav("/Users/annie/Documents/GitHub/Group_H_Election_Covid/Peishan_Li/2020vote.sav")
vote2020<-data.frame(vote2020)
vote2020$mail<-ifelse(vote2020$Q4==3, 1, 0)
analysis2020<-vote2020 %>%
  select(mail, pid3) %>%
  group_by(pid3) %>%
  mutate(partytotal=n()) %>%
  ungroup() %>%
  group_by(pid3, mail) %>%
  mutate(partyvotetype=n()) %>%
  mutate(percentpartyvotetype=percent(partyvotetype/partytotal)) %>%
  filter(row_number()==1) %>%
  select(pid3, mail, partytotal, partyvotetype, percentpartyvotetype) %>%
  filter(pid3==1|pid3==2) %>%
  filter(mail==1) %>%
  arrange(pid3)
analysis2020$Year<-2020
analysis2020$party[analysis2020$pid3==1]<-"Democrat"
analysis2020$party[analysis2020$pid3==2]<-"Republican"
analysis2020$partycolor[analysis2020$party=="Democrat"]<-"blue"
analysis2020$partycolor[analysis2020$party=="Republican"]<-"red"
analysis2020<-data.frame(analysis2020)
analysis2020<-analysis2020 %>%
  select(party, mail, partytotal, partyvotetype, percentpartyvotetype, Year, partycolor)
analysis2020
vote2016<-read.dta("/Users/annie/Documents/GitHub/Group_H_Election_Covid/Peishan_Li/2016vote.dta")
vote2016$mail<-ifelse(vote2016$Q4=="Voted by mail or absentee ballot my mail", 1, 0)
analysis2016<-vote2016 %>%
  select(mail, pid3) %>%
  group_by(pid3) %>%
  mutate(partytotal=n()) %>%
  ungroup() %>%
  group_by(pid3, mail) %>%
  mutate(partyvotetype=n()) %>%
  ungroup() %>%
  mutate(percentpartyvotetype=percent(partyvotetype/partytotal)) %>%
  group_by(pid3, mail) %>%
  filter(row_number()==1) %>%
  select(pid3,mail, partytotal, partyvotetype, percentpartyvotetype) %>%
  filter(pid3=="Democrat"|pid3=="Republican") %>%
  filter(mail==1) %>%
  arrange(pid3)
analysis2016<-rename(analysis2016, c("party"="pid3"))
analysis2016$Year<-2016
for (i in 1:2){
  if (analysis2016$party[i]=="Democrat"){
    analysis2016$partycolor[i]<-"blue"
  }else if (analysis2016$party[i]=="Republican"){
    analysis2016$partycolor[i]<-"red"
  }
}
analysis2016
vote2012<-read.dta("/Users/annie/Documents/GitHub/Group_H_Election_Covid/Peishan_Li/2012vote.dta")
vote2012$mail<-ifelse(vote2012$q4=="Voted by mail (or absentee)", 1, 0)
analysis2012<-vote2012 %>%
  select(mail, pid3) %>%
  group_by(pid3) %>%
  mutate(partytotal=n()) %>%
  ungroup() %>%
  group_by(pid3, mail) %>%
  mutate(partyvotetype=n()) %>%
  ungroup() %>%
  mutate(percentpartyvotetype=percent(partyvotetype/partytotal)) %>%
  group_by(pid3, mail) %>%
  filter(row_number()==1) %>%
  select(pid3,mail, partytotal, partyvotetype, percentpartyvotetype) %>%
  filter(pid3=="Democrat"|pid3=="Republican") %>%
  filter(mail==1) %>%
  arrange(pid3)
analysis2012<-rename(analysis2012, c("party"="pid3"))
analysis2012$Year<-2012
for (i in 1:2){
  if (analysis2012$party[i]=="Democrat"){
    analysis2012$partycolor[i]<-"blue"
  }else if (analysis2012$party[i]=="Republican"){
    analysis2012$partycolor[i]<-"red"
  }
}
analysis2012
vote2008<-read.dta("/Users/annie/Documents/GitHub/Group_H_Election_Covid/Peishan_Li/2008vote.dta")
vote2008$mail<-ifelse(vote2008$q5=="voted by mail (or absentee)", 1, 0)
analysis2008<-vote2008 %>%
  select(mail, pid3) %>%
  group_by(pid3) %>%
  mutate(partytotal=n()) %>%
  ungroup() %>%
  group_by(pid3, mail) %>%
  mutate(partyvotetype=n()) %>%
  ungroup() %>%
  mutate(percentpartyvotetype=percent(partyvotetype/partytotal)) %>%
  group_by(pid3, mail) %>%
  filter(row_number()==1) %>%
  select(pid3,mail, partytotal, partyvotetype, percentpartyvotetype) %>%
  filter(pid3=="democrat "|pid3=="republican ") %>%
  filter(mail==1) %>%
  arrange(pid3)
analysis2008<-rename(analysis2008, c("party"="pid3"))
analysis2008$Year<-2008
analysis2008$party<-as.character(analysis2008$party)
analysis2008$party[analysis2008$party=="democrat "]<-"Democrat"
analysis2008$party[analysis2008$party=="republican "]<-"Republican"
analysis2008$partycolor[analysis2008$party=="Democrat"]<-"blue"
analysis2008$partycolor[analysis2008$party=="Republican"]<-"red"
analysis2008

Combine dataset.

analysisbyparty<-rbind(analysis2020, analysis2016, analysis2012, analysis2008)
analysisbyparty<-rename(analysisbyparty, c("Percentage"="percentpartyvotetype"))
analysisbyparty

By party mail in voting in each election

byparty<-analysisbyparty %>%
  ggplot(.,aes(x=Year,y=Percentage, group=party))+
  theme_bw()+
  geom_line(aes(color=party))+
  geom_point(aes(color=party))+
  scale_color_manual(values=c("Democrat"="blue", "Republican"="red"))+
  theme(legend.position="right")+
  annotate("text", x=2018, y=0.55, label="Democratic Party", color="blue")+
  annotate("text", x=2019, y=0.35, label="Republican Party", color="red")+
  labs(x="Year of Election", y="Percentage of Mail-in Voting", title="Percentage of Mail-in Voting by Party")+
  scale_size_continuous(guide=FALSE)+
  scale_x_discrete(limits=c(2008, 2012, 2016, 2020))+
  theme(plot.title=element_text(hjust = 0.5))
byparty

There is also a sharp increase from 2016 to 2020 by party. Particularly, Democrats favor the idea of mail-in voting much more than Republicans.

Part 2

We’ll then explore if different voting mechanisms could have an impact on number of cases. How does the percentage of mail-in voting affects the increase of Covid-19 cases? Do democratic states and republican states differ in the increase of Covid-19 cases during the whole voting period, since they might have different policies and preferences regarding in person vs mail-in voting at state government level?

Obtain longitude and latitude data of US states.

us.states<-map_data("state")
us.states<-as_data_frame(us.states)
us.states<-rename(us.states, c("state"="region"))
us.states$subregion<-NULL
us.states$state<-str_to_title(us.states$state)
#Add state abbreviations and centers
statenames<-as_data_frame(cbind(state=state.name, state.abb=state.abb, 
                                state.center.x=state.center$x, state.center.y=state.center$y))
statenames<-statenames %>% 
  mutate_each_(funs(as.numeric), vars=c("state.center.x","state.center.y"))
us.states<-left_join(us.states, statenames)
us.states

Find geoid for each us states. Possible reference link could be kjhealy/fips-codes

geoid<-read.csv("/Users/annie/Documents/GitHub/Group_H_Election_Covid/Peishan_Li/state_fips_master.csv")
geoid<-rename(geoid, c("state.abb"="state_abbr"))
geoid<-rename(geoid, c("GEOID"="fips"))
geoid<-geoid %>%
  select(state.abb, GEOID)
#Convert GEOID into characters
geoid$GEOID<-as.character(geoid$GEOID)
#Certain fip-codes need to be pre-processed
geoid$GEOID[geoid$state.abb=="AL"]<-"01"
geoid$GEOID[geoid$state.abb=="AK"]<-"02"
geoid$GEOID[geoid$state.abb=="AZ"]<-"04"
geoid$GEOID[geoid$state.abb=="AR"]<-"05"
geoid$GEOID[geoid$state.abb=="CA"]<-"06"
geoid$GEOID[geoid$state.abb=="CO"]<-"08"
geoid$GEOID[geoid$state.abb=="CT"]<-"09"
#Add fip-codes for District of Columbia
DC<-c("DC","11")
geoid<-rbind(geoid,DC)
geoid

Combine state mail dataset with state abbreviations.

usfullabb<-us.states %>%
  select(state, state.abb) %>%
  group_by(state) %>%
  filter(row_number()==1) %>%
  ungroup()
bystatejoin<-left_join(bystate, usfullabb, by="state")
#A few states miss state abbreviations. Complete the list.
bystatejoin$state.abb[bystatejoin$state=="Alaska"]="AK"
bystatejoin$state.abb[bystatejoin$state=="District of Columbia"]="DC"
bystatejoin$state.abb[bystatejoin$state=="Hawaii"]="HI"
bystatejoin

Combine dataset for number of successful projects with geoid.

bystategeoid<-left_join(bystatejoin, geoid, by="state.abb")
bystategeoid

Obtain shape files of US states using the tigris package.

stateshape<-states(cb=TRUE)

  |                                                                                                                     
  |                                                                                                               |   0%
  |                                                                                                                     
  |=                                                                                                              |   1%
  |                                                                                                                     
  |==                                                                                                             |   1%
  |                                                                                                                     
  |==                                                                                                             |   2%
  |                                                                                                                     
  |===                                                                                                            |   2%
  |                                                                                                                     
  |===                                                                                                            |   3%
  |                                                                                                                     
  |====                                                                                                           |   3%
  |                                                                                                                     
  |====                                                                                                           |   4%
  |                                                                                                                     
  |=====                                                                                                          |   4%
  |                                                                                                                     
  |=====                                                                                                          |   5%
  |                                                                                                                     
  |======                                                                                                         |   5%
  |                                                                                                                     
  |======                                                                                                         |   6%
  |                                                                                                                     
  |=======                                                                                                        |   6%
  |                                                                                                                     
  |=======                                                                                                        |   7%
  |                                                                                                                     
  |========                                                                                                       |   7%
  |                                                                                                                     
  |========                                                                                                       |   8%
  |                                                                                                                     
  |=========                                                                                                      |   8%
  |                                                                                                                     
  |==========                                                                                                     |   9%
  |                                                                                                                     
  |===========                                                                                                    |  10%
  |                                                                                                                     
  |============                                                                                                   |  11%
  |                                                                                                                     
  |=============                                                                                                  |  12%
  |                                                                                                                     
  |==============                                                                                                 |  13%
  |                                                                                                                     
  |===============                                                                                                |  14%
  |                                                                                                                     
  |================                                                                                               |  14%
  |                                                                                                                     
  |================                                                                                               |  15%
  |                                                                                                                     
  |=================                                                                                              |  15%
  |                                                                                                                     
  |=================                                                                                              |  16%
  |                                                                                                                     
  |==================                                                                                             |  16%
  |                                                                                                                     
  |==================                                                                                             |  17%
  |                                                                                                                     
  |====================                                                                                           |  18%
  |                                                                                                                     
  |=====================                                                                                          |  19%
  |                                                                                                                     
  |======================                                                                                         |  19%
  |                                                                                                                     
  |======================                                                                                         |  20%
  |                                                                                                                     
  |=======================                                                                                        |  20%
  |                                                                                                                     
  |=======================                                                                                        |  21%
  |                                                                                                                     
  |========================                                                                                       |  21%
  |                                                                                                                     
  |========================                                                                                       |  22%
  |                                                                                                                     
  |=========================                                                                                      |  22%
  |                                                                                                                     
  |=========================                                                                                      |  23%
  |                                                                                                                     
  |==========================                                                                                     |  23%
  |                                                                                                                     
  |===========================                                                                                    |  24%
  |                                                                                                                     
  |============================                                                                                   |  25%
  |                                                                                                                     
  |=============================                                                                                  |  26%
  |                                                                                                                     
  |=============================                                                                                  |  27%
  |                                                                                                                     
  |==============================                                                                                 |  27%
  |                                                                                                                     
  |===============================                                                                                |  28%
  |                                                                                                                     
  |================================                                                                               |  28%
  |                                                                                                                     
  |================================                                                                               |  29%
  |                                                                                                                     
  |=================================                                                                              |  29%
  |                                                                                                                     
  |=================================                                                                              |  30%
  |                                                                                                                     
  |==================================                                                                             |  30%
  |                                                                                                                     
  |==================================                                                                             |  31%
  |                                                                                                                     
  |===================================                                                                            |  31%
  |                                                                                                                     
  |===================================                                                                            |  32%
  |                                                                                                                     
  |====================================                                                                           |  32%
  |                                                                                                                     
  |====================================                                                                           |  33%
  |                                                                                                                     
  |=====================================                                                                          |  34%
  |                                                                                                                     
  |======================================                                                                         |  34%
  |                                                                                                                     
  |=======================================                                                                        |  35%
  |                                                                                                                     
  |========================================                                                                       |  36%
  |                                                                                                                     
  |=========================================                                                                      |  37%
  |                                                                                                                     
  |==========================================                                                                     |  38%
  |                                                                                                                     
  |=============================================                                                                  |  40%
  |                                                                                                                     
  |==============================================                                                                 |  41%
  |                                                                                                                     
  |==============================================                                                                 |  42%
  |                                                                                                                     
  |===============================================                                                                |  42%
  |                                                                                                                     
  |===============================================                                                                |  43%
  |                                                                                                                     
  |================================================                                                               |  43%
  |                                                                                                                     
  |=================================================                                                              |  44%
  |                                                                                                                     
  |==================================================                                                             |  45%
  |                                                                                                                     
  |===================================================                                                            |  46%
  |                                                                                                                     
  |====================================================                                                           |  46%
  |                                                                                                                     
  |====================================================                                                           |  47%
  |                                                                                                                     
  |=====================================================                                                          |  47%
  |                                                                                                                     
  |======================================================                                                         |  48%
  |                                                                                                                     
  |=======================================================                                                        |  49%
  |                                                                                                                     
  |=======================================================                                                        |  50%
  |                                                                                                                     
  |========================================================                                                       |  50%
  |                                                                                                                     
  |========================================================                                                       |  51%
  |                                                                                                                     
  |=========================================================                                                      |  51%
  |                                                                                                                     
  |=========================================================                                                      |  52%
  |                                                                                                                     
  |==========================================================                                                     |  52%
  |                                                                                                                     
  |==========================================================                                                     |  53%
  |                                                                                                                     
  |===========================================================                                                    |  53%
  |                                                                                                                     
  |============================================================                                                   |  54%
  |                                                                                                                     
  |=============================================================                                                  |  55%
  |                                                                                                                     
  |==============================================================                                                 |  56%
  |                                                                                                                     
  |================================================================                                               |  58%
  |                                                                                                                     
  |=================================================================                                              |  58%
  |                                                                                                                     
  |=================================================================                                              |  59%
  |                                                                                                                     
  |==================================================================                                             |  60%
  |                                                                                                                     
  |===================================================================                                            |  60%
  |                                                                                                                     
  |====================================================================                                           |  61%
  |                                                                                                                     
  |====================================================================                                           |  62%
  |                                                                                                                     
  |=====================================================================                                          |  62%
  |                                                                                                                     
  |=====================================================================                                          |  63%
  |                                                                                                                     
  |======================================================================                                         |  63%
  |                                                                                                                     
  |=======================================================================                                        |  64%
  |                                                                                                                     
  |========================================================================                                       |  65%
  |                                                                                                                     
  |=========================================================================                                      |  65%
  |                                                                                                                     
  |=========================================================================                                      |  66%
  |                                                                                                                     
  |==========================================================================                                     |  66%
  |                                                                                                                     
  |===========================================================================                                    |  67%
  |                                                                                                                     
  |=============================================================================                                  |  69%
  |                                                                                                                     
  |==============================================================================                                 |  70%
  |                                                                                                                     
  |===============================================================================                                |  71%
  |                                                                                                                     
  |================================================================================                               |  72%
  |                                                                                                                     
  |==================================================================================                             |  74%
  |                                                                                                                     
  |====================================================================================                           |  75%
  |                                                                                                                     
  |====================================================================================                           |  76%
  |                                                                                                                     
  |=====================================================================================                          |  76%
  |                                                                                                                     
  |=====================================================================================                          |  77%
  |                                                                                                                     
  |============================================================================================                   |  83%
  |                                                                                                                     
  |==============================================================================================                 |  84%
  |                                                                                                                     
  |===============================================================================================                |  85%
  |                                                                                                                     
  |================================================================================================               |  87%
  |                                                                                                                     
  |===================================================================================================            |  89%
  |                                                                                                                     
  |====================================================================================================           |  90%
  |                                                                                                                     
  |======================================================================================================         |  92%
  |                                                                                                                     
  |===========================================================================================================    |  96%
  |                                                                                                                     
  |===============================================================================================================| 100%

Read in covid cases data. Data source is United States CDC

covid<-read.csv("/Users/annie/Documents/GitHub/Group_H_Election_Covid/Peishan_Li/United_States_COVID-19_Cases_and_Deaths_by_State_over_Time.csv")

Keep only data during the voting period. The election day is November 3, and the earliest voting time is 46 days before the election day. Reference from Early Voting Calendar. The end of our observation date is 7 days after the election day.

covid$submission_date<-as.Date(covid$submission_date, "%m/%d/%Y")
#Filter data during the voting peiord
covid<-covid %>%
  arrange(submission_date) %>%
  filter(submission_date>="2020-09-17" &submission_date<="2020-11-10")
#General view
covid<-covid %>%
  group_by(submission_date, state) %>%
  mutate(dailytotal=sum(tot_cases)) %>%
  ungroup() %>%
  group_by(state) %>%
  mutate(statetotalduringvoting=sum(tot_cases)) %>%
  ungroup() %>%
  select(submission_date, state, tot_cases, dailytotal, statetotalduringvoting)
covid<-rename(covid, "state.abb"="state")
covid

To make the number of cases comparable, they need to be weighted by state population. Data Source is United States Census Bureau

population<-read.csv("/Users/annie/Documents/GitHub/Group_H_Election_Covid/Peishan_Li/nst-est2020.csv")

Keep only population estimate of 2020 and at state level.

population<-population %>%
  select(NAME, POPESTIMATE2020) %>%
  filter(NAME!="United States" & NAME!="Northeast Region" & NAME!="Midwest Region" & NAME!="South Region" & NAME!="West Region")
population<-rename(population, c("state"="NAME"))
population<-rename(population, c("popestimate"="POPESTIMATE2020"))
population

Combine covid dataset with population dataset and calculate the percentages of cases within the state populations.

population<-left_join(population, usfullabb, by="state")
population$state.abb[population$state=="Alaska"]="AK"
population$state.abb[population$state=="District of Columbia"]="DC"
population$state.abb[population$state=="Hawaii"]="HI"
population
covidw<-left_join(population, covid, by="state.abb")
covidw
covidw<-covidw %>%
  arrange(submission_date) %>%
  mutate(dailytotalw=round(dailytotal/popestimate*1000000)) %>%
  mutate(statetotalw=round(statetotalduringvoting/popestimate*1000000))
covidw

Total number in each state weighted

totalcovid<-covidw %>%
  group_by(state.abb) %>%
  filter(row_number()==1) %>%
  ungroup() %>%
  select(state, popestimate, state.abb, statetotalduringvoting, statetotalw)
totalcovid
totalcovid<-rename(totalcovid, c("STATE"="state"))
totalcovidgeoid<-left_join(totalcovid, geoid, by="state.abb")
alldata<-left_join(totalcovidgeoid, bystategeoid, by="GEOID")
alldata$state.abb.y<-NULL
alldata$state<-NULL
alldata<-rename(alldata, "state.abb"="state.abb.x")
alldata$mail<-as.numeric(alldata$mail)
alldata

Merge state map data with weighted covid cases.

allbystate=geo_join(stateshape, alldata, "STATEFP", "GEOID")
allbystate
Simple feature collection with 56 features and 22 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -179.1489 ymin: -14.5487 xmax: 179.7785 ymax: 71.36516
Geodetic CRS:  NAD83
First 10 features:
   STATEFP  STATENS    AFFGEOID GEOID STUSPS                                         NAME LSAD        ALAND      AWATER
1       12 00294478 0400000US12    12     FL                                      Florida   00 138947364717 31362872853
2       78 01802710 0400000US78    78     VI                 United States Virgin Islands   00    348021896  1550236199
3       30 00767982 0400000US30    30     MT                                      Montana   00 376966832749  3869031338
4       27 00662849 0400000US27    27     MN                                    Minnesota   00 206230065476 18942261495
5       24 01714934 0400000US24    24     MD                                     Maryland   00  25151726296  6979340970
6       45 01779799 0400000US45    45     SC                               South Carolina   00  77864659170  5075874513
7       23 01779787 0400000US23    23     ME                                        Maine   00  79887659040 11745717739
8       15 01779782 0400000US15    15     HI                                       Hawaii   00  16634006436 11777792811
9       11 01702382 0400000US11    11     DC                         District of Columbia   00    158340389    18687196
10      69 01779809 0400000US69    69     MP Commonwealth of the Northern Mariana Islands   00    472292529  4644252458
                  STATE popestimate state.abb statetotalduringvoting statetotalw      mail Democrat Republican    DandR
1               Florida    21733312        FL               40741674     1874619 0.4768405 37.80221  31.526210 69.32842
2                  <NA>          NA      <NA>                     NA          NA        NA       NA         NA       NA
3               Montana     1080577        MT                1220613     1129594 0.8865553 28.04969  28.768770 56.81846
4             Minnesota     5657342        MN                6744329     1192137 0.5044857 43.25591  24.136840 67.39275
5              Maryland     6055802        MD                7426305     1226312 0.6022226 49.72233  18.556010 68.27834
6        South Carolina     5218040        SC                8916426     1708769 0.2667850 26.55966  34.577920 61.13758
7                 Maine     1350141        ME                 332357      246165 0.4672680 36.41784  27.790270 64.20811
8                Hawaii     1407006        HI                 748848      532228 0.9101848 47.71746  15.341520 63.05898
9  District of Columbia      712816        DC                 892451     1252008 0.7028656 76.07684   2.372092 78.44893
10                 <NA>          NA      <NA>                     NA          NA        NA       NA         NA       NA
   Democratpercent Republicanpercent party rank                       geometry
1           54.53%            45.47%  blue    1 MULTIPOLYGON (((-80.17628 2...
2               NA                NA  <NA>   NA MULTIPOLYGON (((-64.62799 1...
3           49.37%            50.63%   red    1 MULTIPOLYGON (((-116.0491 4...
4           64.18%            35.82%  blue    1 MULTIPOLYGON (((-89.59206 4...
5           72.82%            27.18%  blue    1 MULTIPOLYGON (((-76.05015 3...
6           43.44%            56.56%   red    1 MULTIPOLYGON (((-79.50795 3...
7           56.72%            43.28%  blue    1 MULTIPOLYGON (((-67.32259 4...
8           75.67%            24.33%  blue    1 MULTIPOLYGON (((-156.0608 1...
9           96.98%             3.02%  blue    1 MULTIPOLYGON (((-77.11976 3...
10              NA                NA  <NA>   NA MULTIPOLYGON (((146.051 16....

Mail-in voting percentage & typical D/R state interactive plot

Provide a leaflet map, where polygons are used to reflect the percentage of mail-in voting. Each state is categorized as a typical Democratic state or a Republican state based on the percentage of Democrats and Republicans from the 2020 SPAE, which is represented by the color of the state’s border on the map.

content<-paste("State:", allbystate$STATE, "<br/>",
               "Total number of cases:", allbystate$statetotalduringvoting, "<br/>",
               "Weighted total number of cases:", allbystate$statetotalw, "<br/>",
              "Percentage of mail-in voting:", allbystate$mail, "<br/>",
              "Percentage of Democrats in All Democrats and Republicans:", allbystate$Democratpercent, "<br/>",
              "Percentage of Republicans in All Democrats and Republicans:", allbystate$Republicanpercent, "<br/>")
pal=colorNumeric(palette="Greens", domain=allbystate$mail) 
leafletmap1<-leaflet() %>%
  addTiles() %>%
  addProviderTiles("Stamen.TonerLite") %>%
  setView(-98.1156, 38.4204, zoom=4) %>%
  addPolygons(group="Mail-in Voting Percentage", data=allbystate, fillColor=~pal(allbystate$mail), color=allbystate$party, fillOpacity=0.7, weight=2, smoothFactor=0.2, popup=content, label=~stringr::str_c(NAME, 'See pop-up for more info'), labelOptions=labelOptions(direction='auto'), highlightOptions=highlightOptions(color=allbystate$party, weight=5, bringToFront=TRUE, sendToBack=TRUE)) %>%
  addLegend("bottomright", pal=pal, values=allbystate$mail, title="State Mail-in Voting Percentage", opacity=1)
leafletmap1

Weighted Covid cases & typical D/R state interactive plot

Provide a leaflet map, where polygons are used to reflect the percentage of covid cases increase in the voting period till 7 days after election day. Each state is categorized as a typical Democratic state or a Republican state based on the percentage of Democrats and Republicans from the 2020 SPAE, which is represented by the color of the state’s border on the map.

content<-paste("State:", allbystate$STATE, "<br/>",
               "Total number of cases:", allbystate$statetotalduringvoting, "<br/>",
               "Weighted total number of cases:", allbystate$statetotalw, "<br/>",
              "Percentage of mail-in voting:", allbystate$mail, "<br/>",
              "Percentage of Democrats in All Democrats and Republicans:", allbystate$Democratpercent, "<br/>",
              "Percentage of Republicans in All Democrats and Republicans:", allbystate$Republicanpercent, "<br/>")
pal=colorNumeric(palette="Oranges", domain=allbystate$statetotalw) 
leafletmap2<-leaflet() %>%
  addTiles() %>%
  addProviderTiles("Stamen.TonerLite") %>%
  setView(-98.1156, 38.4204, zoom=4) %>%
  addPolygons(data=allbystate, fillColor=~pal(allbystate$statetotalw), color=allbystate$party, fillOpacity=0.7, weight=2, smoothFactor=0.2, popup=content, label=~stringr::str_c(NAME, ' See pop-up for more info'), labelOptions=labelOptions(direction='auto'), highlightOptions=highlightOptions(color=allbystate$party, weight=5, bringToFront=TRUE, sendToBack=TRUE)) %>%
  addLegend("bottomright", pal=pal, values=allbystate$statetotalw, title="State Weighted Covid Cases Increase During Voting Period", opacity=1)
leafletmap2

Run a regression to see the relationship between mail-in voting percentage and weighted covid cases and visualize the relationship.

lm<-lm(log(statetotalw)~mail, data=alldata)
summary(lm)

Call:
lm(formula = log(statetotalw) ~ mail, data = alldata)

Residuals:
    Min      1Q  Median      3Q     Max 
-1.7131 -0.1719  0.1612  0.3351  0.7315 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  14.2730     0.1571  90.855   <2e-16 ***
mail         -0.6944     0.3009  -2.308   0.0253 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.5118 on 49 degrees of freedom
Multiple R-squared:  0.09802,   Adjusted R-squared:  0.07961 
F-statistic: 5.325 on 1 and 49 DF,  p-value: 0.02529

The result suggests that on average, 1 percent increase in mail-in voting proportion leads to a 69.4 percent decrease of weighted covid cases in a state, not taking into other factors into account, and the influence is significant.

Plot the relationship grouped by Democratic and Republican states.

alldata$partyname[alldata$party=="blue"]<-"Democrat"
alldata$partyname[alldata$party=="red"]<-"Republican"
relationship<-ggplot(alldata, aes(x=mail, y=log(statetotalw), group=partyname))+
  theme_bw()+
  geom_point(aes(color=partyname))+
  geom_smooth(aes(color=partyname),method="lm", formula=y~x, se=FALSE)+
  scale_color_manual(values=c("Democrat"="blue", "Republican"="red"))+
  theme(legend.position="right")+
  labs(x="Percentage of mail-in voting", y="Total covid cases in a state (taken logarithm)", title="Relationship between mail-in voting and covid cases increase")+
  theme(plot.title=element_text(hjust=0.5))
relationship

LS0tCnRpdGxlOiAiR3JvdXAgSCBHcm91cCBQcm9qZWN0IgphdXRob3I6ICJMaSBQZWlzaGFuIgpkYXRlOiAiMy8zMC8yMDIxIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogeWVzCiAgICBkZl9wcmludDogcGFnZWQKICAgIHRoZW1lOiBqb3VybmFsICAgCiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogeWVzCiAgICB0aGVtZTogam91cm5hbAotLS0KPHN0eWxlPgpib2R5eyAvKiBOb3JtYWwgKi8KZm9udC1zaXplOiAxNXB4Owpjb2xvcjogYmxhY2s7Cn0Kd3JpdGUgeyAgCmxpbmUtaGVpZ2h0OiA3ZW07Cn0KdGFibGUgeyAvKiBUYWJsZSAqLwpmb250LXNpemU6IDEycHg7Cn0KaDEgeyAvKiBIZWFkZXIgMSAqLwpmb250LXNpemU6IDMwcHg7Cn0KaDIgeyAvKiBIZWFkZXIgMiAqCmZvbnQtc2l6ZTogMjZweDsKfQpoMyB7IC8qIEhlYWRlciAzICovCmZvbnQtc2l6ZTogMjJweDsKfQpjb2RlLnJ7IC8qIENvZGUgYmxvY2sgKi8KZm9udC1zaXplOiAxNHB4Owp9CnByZSB7IC8qIENvZGUgYmxvY2sgKi8KZm9udC1zaXplOiAxNHB4Cn0KLm1haW4tY29udGFpbmVyIHsKICAgIHdpZHRoOiA4MCU7CiAgICBtYXgtd2lkdGg6IHVuc2V0Owp9Cjwvc3R5bGU+CgpgYGB7ciBzZXR1cCwgZWNobz1UUlVFLCBldmFsPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvPVRSVUUsZXZhbD1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFKQpgYGAKCkxvYWQgcGFja2FnZXM6CmBgYHtyLCBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KbGlicmFyeShyZWFkeGwpCmxpYnJhcnkoZm9yZWlnbikKbGlicmFyeShoYXZlbikKbGlicmFyeShtYWdyaXR0cikKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKSAgICAKbGlicmFyeShwbG90bHkpCmxpYnJhcnkoZ2dtYXApCmxpYnJhcnkoZ2d0aGVtZXMpCmxpYnJhcnkoZ2dwdWJyKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShyZ2RhbCkKbGlicmFyeShvc21kYXRhKQpsaWJyYXJ5KG5vbWluYXRpbSkKbGlicmFyeShqc29ubGl0ZSkKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmxpYnJhcnkoRFQpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkobGVhZmxldCkKbGlicmFyeShmb3JtYXR0YWJsZSkKbGlicmFyeSh0aWdyaXMpCmxpYnJhcnkoaHRtbHdpZGdldHMpCmxpYnJhcnkoc2YpCmxpYnJhcnkoZ2dhbmltYXRlKQpsaWJyYXJ5KHdlYnNob3QpCmxpYnJhcnkobWFwdG9vbHMpCmxpYnJhcnkocmdlb3MpCmxpYnJhcnkocmdkYWwpCmBgYAoKCiMgVGhlIHJlbGF0aW9uc2hpcCBvZiBpbiBwZXJzb24gdm90aW5nIFZTIG1haWwtaW4gdm90aW5nIGFuZCBDb3ZpZC0xOSBjYXNlIGRldmVsb3BtZW50CgpXZSB3YW50IHRvIGV4cGxvcmUgdGhlIHJlbGF0aW9uc2hpcCBvZiBpbiBwZXJzb24gdm90aW5nIFZTIG1haWwtaW4gdm90aW5nIGFuZCBDb3ZpZC0xOSBjYXNlIGRldmVsb3BtZW50LgoKIyMgUGFydCAxCgpGaXJzdGx5LCB3ZSBhcmd1ZSB0aGF0IHRoZSBvdmVyYWxsIHBhbmRlbWljIHNpdHVhdGlvbiBiZWZvcmUgdGhlIHZvdGluZyBwZXJpb2Qgc3RhcnRzIG1pZ2h0IGxlYWQgdG8gcGVvcGxlJ3MgcHJlZmVyZW5jZSBvZiBtYWlsLWluIHZvdGluZy4gVGhpcyBjb3VsZCBiZSBzb21ld2hhdCBwcm92ZWQgYnkgdGhlIGZhY3QgdGhhdCBwZW9wbGUgd2hvIGFyZSBhYnNlbmNlIG9mIGluIHBlcnNvbiB2b3RpbmcgY291bGQgcmVnaXN0ZXIgZm9yIG1haWwgYmFsbG90IGFuZCBmaWxsIGluICJDb3ZpZCIgYXMgdGhlIGV4Y3VzZS4KClRvIHVuZGVyc3RhbmQgdGhpcywgYSBncmFwaCBvZiB0aGUgY2hhbmdlIGluIG1haWwtaW4gdm90aW5nIHByZWZlcmVuY2UgZnJvbSAyMDE2IGVsZWN0aW9uIHRvIDIwMjAgZWxlY3Rpb24gY291bGQgYmUgZHJhZnRlZC4gU3BlY2lmaWNhbGx5LCB0aGUgYmFja2dyb3VuZCBrbm93bGVkZ2Ugc3VnZ2VzdHMgdGhhdCBUcnVtcCBhZG1pbmlzdHJhdGlvbiBhbmQgaXRzIHN1cHBvcnRlcnMgb3Bwb3NlIG1haWwtaW4gdm90aW5nLCBzbyB3ZSdsbCBhbHNvIGJlIGxvb2tpbmcgYXQgdGhlIGRpZmZlcmVuY2Ugb2YgbWFpbC1pbiB2b3RpbmcgcHJlZmVyZW5jZSBjaGFuZ2UgZnJvbSAyMDE2IGVsZWN0aW9uIHRvIDIwMjAgZWxlY3Rpb24gZm9yIERlbW9jcmF0cyBhbmQgUmVwdWJsaWNhbnMgcmVzcGVjdGl2ZWx5LgoKUmVhZCBpbiBpbmZvcm1hdGlvbiBvbiB0aGUgcGVyY2VudGFnZSBvZiBtYWlsLWluIHZvdGluZyBhcyB3ZWxsIGFzIHRoZSBwcm9wb3J0aW9uIG9mIHBlb3BsZSBvZiBkaWZmZXJlbnQgcGFydGllcyB3aXRoaW4gZWFjaCBzdGF0ZS4gU3BlY2lmaWNhbGx5LCBkYXRhIGNob3NlbiBmcm9tIFNQQUUgaXMgdG9wLWxpbmUgc3RhdGlzdGljcyBmcm9tIG5hdGlvbndpZGUgc3R1ZHksIGJ5IHN0YXRlLCB3ZWlnaHRlZCBkYXRhLgoKKkRhdGEgU291cmNlOiBTdGV3YXJ0LCBDaGFybGVzLCAyMDIxLCAiMjAyMCBTdXJ2ZXkgb2YgdGhlIFBlcmZvcm1hbmNlIG9mIEFtZXJpY2FuIEVsZWN0aW9ucyIsIGh0dHBzOi8vZG9pLm9yZy8xMC43OTEwL0RWTi9GU0dYN1osIEhhcnZhcmQgRGF0YXZlcnNlLCBWMSwgVU5GOjY6NzBLVzR1b3V1VERUODYwTWlQSnEzQT09IFtmaWxlVU5GXSoKYGBge3IgaW1wb3J0IGRhdGEsIGVjaG89VFJVRSwgZXZhbD1UUlVFfQp2b3RlPC1yZWFkLmNzdigiL1VzZXJzL2FubmllL0RvY3VtZW50cy9HaXRIdWIvR3JvdXBfSF9FbGVjdGlvbl9Db3ZpZC9QZWlzaGFuX0xpL3dlaWdodGVkdm90ZS5jc3YiKQpwaWQzPC1yZWFkLmNzdigiL1VzZXJzL2FubmllL0RvY3VtZW50cy9HaXRIdWIvR3JvdXBfSF9FbGVjdGlvbl9Db3ZpZC9QZWlzaGFuX0xpL3BpZDMuY3N2IikKYGBgCgpgYGB7ciB2b3RlIGFuZCBwaWQzIGJ5IHN0YXRlLCBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KYnlzdGF0ZTwtaW5uZXJfam9pbih2b3RlLCBwaWQzLCBieT0naWQnKQpieXN0YXRlPC1yZW5hbWUoYnlzdGF0ZSwgYygic3RhdGUiPSJpZCIpKQpieXN0YXRlPC1yZW5hbWUoYnlzdGF0ZSwgYygibWFpbCI9IlZvdGVkLmJ5Lm1haWwub3IuYWJzZW50ZWUuYmFsbG90LmJ5Lm1haWwuLmluY2x1ZGluZy5kcm9wcGluZy5vZmYuYS5iYWxsb3QudGhhdC53YXMubWFpbGVkLnRvLnlvdS4iKSkKYnlzdGF0ZTwtYnlzdGF0ZSAlPiUKICBzZWxlY3Qoc3RhdGUsIG1haWwsIERlbW9jcmF0LCBSZXB1YmxpY2FuKSAlPiUKICBtdXRhdGUoRGFuZFI9RGVtb2NyYXQrUmVwdWJsaWNhbikgJT4lCiAgbXV0YXRlKERlbW9jcmF0cGVyY2VudD1wZXJjZW50KERlbW9jcmF0L0RhbmRSKSklPiUKICBtdXRhdGUoUmVwdWJsaWNhbnBlcmNlbnQ9cGVyY2VudChSZXB1YmxpY2FuL0RhbmRSKSkKYnlzdGF0ZSRtYWlsPC1wZXJjZW50KGJ5c3RhdGUkbWFpbC8xMDApCiNQcmVwYXJlIGNvbG9yIGluZm9ybWF0aW9uIGZvciBmdXJ0aGVyIHBsb3R0aW5nCmZvciAoaSBpbiAxOjUxKXsKICBpZiAoYnlzdGF0ZSREZW1vY3JhdFtpXTxieXN0YXRlJFJlcHVibGljYW5baV0pewogICAgYnlzdGF0ZSRwYXJ0eVtpXT0icmVkIgogIH1lbHNlIGlmIChieXN0YXRlJERlbW9jcmF0W2ldPmJ5c3RhdGUkUmVwdWJsaWNhbltpXSl7CiAgICBieXN0YXRlJHBhcnR5W2ldPSJibHVlIgogIH1lbHNlIGlmIChieXN0YXRlJERlbW9jcmF0W2ldPT1ieXN0YXRlJFJlcHVibGljYW5baV0pewogICAgYnlzdGF0ZSRwYXJ0eVtpXT0iI2IyYWVhZSIKICB9Cn0KYnlzdGF0ZQpgYGAKCkluIHRoZSBtZWFudGltZSwgYWNjb3JkaW5nIHRvIHBhc3QgZmluYWwgcmVwb3J0cyBmcm9tIFNQQUUgYWxzbyBhdmFpbGFibGUgZnJvbSB0aGUgbGluayBhYm92ZSwgdGhlIG1haWwtaW4gdm90aW5nIHBlcmNlbnRhZ2Ugb2YgZWFjaCBwYXN0IGVsZWN0aW9uIGF0IGNvdW50cnkgbGV2ZWwgY291bGQgYmUgc3VtbWFyaXplZCBhczoKYGBge3Igb3ZlcmFsbCBtYWlsIHBlcmNlbnRhZ2UsIGVjaG89VFJVRSwgZXZhbD1UUlVFfQpvdmVyYWxsbWFpbHBlcmNlbnRhZ2U8LWRhdGEuZnJhbWUoWWVhcj1jKDIwMDAsIDIwMDQsIDIwMDgsIDIwMTIsIDIwMTYsIDIwMjApLCBQZXJjZW50YWdlPWMocGVyY2VudCgwLjEwKSwgcGVyY2VudCgwLjEzKSwgcGVyY2VudCgwLjE2KSwgcGVyY2VudCgwLjE5KSwgcGVyY2VudCgwLjIxKSwgcGVyY2VudCgwLjQ2KSkpCm92ZXJhbGxtYWlscGVyY2VudGFnZQpgYGAKCiMjIyBQZXJjZW50YWdlIG9mIG1haWwtaW4gdm90aW5nIGluIGVhY2ggZWxlY3Rpb24KCmBgYHtyIG92ZXJhbGwgcGxvdCwgZWNobz1UUlVFLCBldmFsPVRSVUUsIGZpZy5hbGlnbj0iY2VudGVyIn0Kb3ZlcmFsbDwtb3ZlcmFsbG1haWxwZXJjZW50YWdlICU+JQogIGdncGxvdCguLGFlcyh4PVllYXIseT1QZXJjZW50YWdlKSkrCiAgdGhlbWVfYncoKSsKICBnZW9tX2xpbmUoY29sb3I9ImxpZ2h0c3RlZWxibHVlMiIpKwogIGdlb21fcG9pbnQoYWVzKHNpemU9UGVyY2VudGFnZSksIGNvbG9yPSJjb3JhbCIpKwogIGxhYnMoeD0iWWVhciBvZiBFbGVjdGlvbiIsIHk9IlBlcmNlbnRhZ2Ugb2YgTWFpbC1pbiBWb3RpbmciLCB0aXRsZT0iUGVyY2VudGFnZSBvZiBNYWlsLWluIFZvdGluZyBpbiBFYWNoIEVsZWN0aW9uIikrCiAgc2NhbGVfc2l6ZV9jb250aW51b3VzKGd1aWRlPUZBTFNFKSsKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz1jKDIwMDAsIDIwMDQsIDIwMDgsIDIwMTIsIDIwMTYsIDIwMjApKSsKICB0aGVtZShwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCm92ZXJhbGwKYGBgCgpUaGUgZ3JhcGhzIGRpc3BsYXkgYSBnZW5lcmFsIHNoYXJwIGluY3JlYXNlIGluIG1haWwtaW4gdm90aW5nIHBlcmNlbnRhZ2UgZnJvbSAyMDE2IHRvIDIwMjAsIHdoaWNoIGNvdWxkIHdlbGwgYmUgZHVlIHRvIHRoZSBDb3ZpZC0xOSBkZXZlbG9wbWVudC4KCmBgYHtyIDIwMjAsIGVjaG89VFJVRSwgZXZhbD1UUlVFfQp2b3RlMjAyMDwtcmVhZF9zYXYoIi9Vc2Vycy9hbm5pZS9Eb2N1bWVudHMvR2l0SHViL0dyb3VwX0hfRWxlY3Rpb25fQ292aWQvUGVpc2hhbl9MaS8yMDIwdm90ZS5zYXYiKQp2b3RlMjAyMDwtZGF0YS5mcmFtZSh2b3RlMjAyMCkKdm90ZTIwMjAkbWFpbDwtaWZlbHNlKHZvdGUyMDIwJFE0PT0zLCAxLCAwKQphbmFseXNpczIwMjA8LXZvdGUyMDIwICU+JQogIHNlbGVjdChtYWlsLCBwaWQzKSAlPiUKICBncm91cF9ieShwaWQzKSAlPiUKICBtdXRhdGUocGFydHl0b3RhbD1uKCkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBncm91cF9ieShwaWQzLCBtYWlsKSAlPiUKICBtdXRhdGUocGFydHl2b3RldHlwZT1uKCkpICU+JQogIG11dGF0ZShwZXJjZW50cGFydHl2b3RldHlwZT1wZXJjZW50KHBhcnR5dm90ZXR5cGUvcGFydHl0b3RhbCkpICU+JQogIGZpbHRlcihyb3dfbnVtYmVyKCk9PTEpICU+JQogIHNlbGVjdChwaWQzLCBtYWlsLCBwYXJ0eXRvdGFsLCBwYXJ0eXZvdGV0eXBlLCBwZXJjZW50cGFydHl2b3RldHlwZSkgJT4lCiAgZmlsdGVyKHBpZDM9PTF8cGlkMz09MikgJT4lCiAgZmlsdGVyKG1haWw9PTEpICU+JQogIGFycmFuZ2UocGlkMykKYW5hbHlzaXMyMDIwJFllYXI8LTIwMjAKYW5hbHlzaXMyMDIwJHBhcnR5W2FuYWx5c2lzMjAyMCRwaWQzPT0xXTwtIkRlbW9jcmF0IgphbmFseXNpczIwMjAkcGFydHlbYW5hbHlzaXMyMDIwJHBpZDM9PTJdPC0iUmVwdWJsaWNhbiIKYW5hbHlzaXMyMDIwJHBhcnR5Y29sb3JbYW5hbHlzaXMyMDIwJHBhcnR5PT0iRGVtb2NyYXQiXTwtImJsdWUiCmFuYWx5c2lzMjAyMCRwYXJ0eWNvbG9yW2FuYWx5c2lzMjAyMCRwYXJ0eT09IlJlcHVibGljYW4iXTwtInJlZCIKYW5hbHlzaXMyMDIwPC1kYXRhLmZyYW1lKGFuYWx5c2lzMjAyMCkKYW5hbHlzaXMyMDIwPC1hbmFseXNpczIwMjAgJT4lCiAgc2VsZWN0KHBhcnR5LCBtYWlsLCBwYXJ0eXRvdGFsLCBwYXJ0eXZvdGV0eXBlLCBwZXJjZW50cGFydHl2b3RldHlwZSwgWWVhciwgcGFydHljb2xvcikKYW5hbHlzaXMyMDIwCmBgYAoKYGBge3IgMjAxNiwgZWNobz1UUlVFLCBldmFsPVRSVUV9CnZvdGUyMDE2PC1yZWFkLmR0YSgiL1VzZXJzL2FubmllL0RvY3VtZW50cy9HaXRIdWIvR3JvdXBfSF9FbGVjdGlvbl9Db3ZpZC9QZWlzaGFuX0xpLzIwMTZ2b3RlLmR0YSIpCnZvdGUyMDE2JG1haWw8LWlmZWxzZSh2b3RlMjAxNiRRND09IlZvdGVkIGJ5IG1haWwgb3IgYWJzZW50ZWUgYmFsbG90IG15IG1haWwiLCAxLCAwKQphbmFseXNpczIwMTY8LXZvdGUyMDE2ICU+JQogIHNlbGVjdChtYWlsLCBwaWQzKSAlPiUKICBncm91cF9ieShwaWQzKSAlPiUKICBtdXRhdGUocGFydHl0b3RhbD1uKCkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBncm91cF9ieShwaWQzLCBtYWlsKSAlPiUKICBtdXRhdGUocGFydHl2b3RldHlwZT1uKCkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUocGVyY2VudHBhcnR5dm90ZXR5cGU9cGVyY2VudChwYXJ0eXZvdGV0eXBlL3BhcnR5dG90YWwpKSAlPiUKICBncm91cF9ieShwaWQzLCBtYWlsKSAlPiUKICBmaWx0ZXIocm93X251bWJlcigpPT0xKSAlPiUKICBzZWxlY3QocGlkMyxtYWlsLCBwYXJ0eXRvdGFsLCBwYXJ0eXZvdGV0eXBlLCBwZXJjZW50cGFydHl2b3RldHlwZSkgJT4lCiAgZmlsdGVyKHBpZDM9PSJEZW1vY3JhdCJ8cGlkMz09IlJlcHVibGljYW4iKSAlPiUKICBmaWx0ZXIobWFpbD09MSkgJT4lCiAgYXJyYW5nZShwaWQzKQphbmFseXNpczIwMTY8LXJlbmFtZShhbmFseXNpczIwMTYsIGMoInBhcnR5Ij0icGlkMyIpKQphbmFseXNpczIwMTYkWWVhcjwtMjAxNgpmb3IgKGkgaW4gMToyKXsKICBpZiAoYW5hbHlzaXMyMDE2JHBhcnR5W2ldPT0iRGVtb2NyYXQiKXsKICAgIGFuYWx5c2lzMjAxNiRwYXJ0eWNvbG9yW2ldPC0iYmx1ZSIKICB9ZWxzZSBpZiAoYW5hbHlzaXMyMDE2JHBhcnR5W2ldPT0iUmVwdWJsaWNhbiIpewogICAgYW5hbHlzaXMyMDE2JHBhcnR5Y29sb3JbaV08LSJyZWQiCiAgfQp9CmFuYWx5c2lzMjAxNgpgYGAKCmBgYHtyIDIwMTIsIGVjaG89VFJVRSwgZXZhbD1UUlVFfQp2b3RlMjAxMjwtcmVhZC5kdGEoIi9Vc2Vycy9hbm5pZS9Eb2N1bWVudHMvR2l0SHViL0dyb3VwX0hfRWxlY3Rpb25fQ292aWQvUGVpc2hhbl9MaS8yMDEydm90ZS5kdGEiKQp2b3RlMjAxMiRtYWlsPC1pZmVsc2Uodm90ZTIwMTIkcTQ9PSJWb3RlZCBieSBtYWlsIChvciBhYnNlbnRlZSkiLCAxLCAwKQphbmFseXNpczIwMTI8LXZvdGUyMDEyICU+JQogIHNlbGVjdChtYWlsLCBwaWQzKSAlPiUKICBncm91cF9ieShwaWQzKSAlPiUKICBtdXRhdGUocGFydHl0b3RhbD1uKCkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBncm91cF9ieShwaWQzLCBtYWlsKSAlPiUKICBtdXRhdGUocGFydHl2b3RldHlwZT1uKCkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUocGVyY2VudHBhcnR5dm90ZXR5cGU9cGVyY2VudChwYXJ0eXZvdGV0eXBlL3BhcnR5dG90YWwpKSAlPiUKICBncm91cF9ieShwaWQzLCBtYWlsKSAlPiUKICBmaWx0ZXIocm93X251bWJlcigpPT0xKSAlPiUKICBzZWxlY3QocGlkMyxtYWlsLCBwYXJ0eXRvdGFsLCBwYXJ0eXZvdGV0eXBlLCBwZXJjZW50cGFydHl2b3RldHlwZSkgJT4lCiAgZmlsdGVyKHBpZDM9PSJEZW1vY3JhdCJ8cGlkMz09IlJlcHVibGljYW4iKSAlPiUKICBmaWx0ZXIobWFpbD09MSkgJT4lCiAgYXJyYW5nZShwaWQzKQphbmFseXNpczIwMTI8LXJlbmFtZShhbmFseXNpczIwMTIsIGMoInBhcnR5Ij0icGlkMyIpKQphbmFseXNpczIwMTIkWWVhcjwtMjAxMgpmb3IgKGkgaW4gMToyKXsKICBpZiAoYW5hbHlzaXMyMDEyJHBhcnR5W2ldPT0iRGVtb2NyYXQiKXsKICAgIGFuYWx5c2lzMjAxMiRwYXJ0eWNvbG9yW2ldPC0iYmx1ZSIKICB9ZWxzZSBpZiAoYW5hbHlzaXMyMDEyJHBhcnR5W2ldPT0iUmVwdWJsaWNhbiIpewogICAgYW5hbHlzaXMyMDEyJHBhcnR5Y29sb3JbaV08LSJyZWQiCiAgfQp9CmFuYWx5c2lzMjAxMgpgYGAKCmBgYHtyIDIwMDgsIGVjaG89VFJVRSwgZXZhbD1UUlVFfQp2b3RlMjAwODwtcmVhZC5kdGEoIi9Vc2Vycy9hbm5pZS9Eb2N1bWVudHMvR2l0SHViL0dyb3VwX0hfRWxlY3Rpb25fQ292aWQvUGVpc2hhbl9MaS8yMDA4dm90ZS5kdGEiKQp2b3RlMjAwOCRtYWlsPC1pZmVsc2Uodm90ZTIwMDgkcTU9PSJ2b3RlZCBieSBtYWlsIChvciBhYnNlbnRlZSkiLCAxLCAwKQphbmFseXNpczIwMDg8LXZvdGUyMDA4ICU+JQogIHNlbGVjdChtYWlsLCBwaWQzKSAlPiUKICBncm91cF9ieShwaWQzKSAlPiUKICBtdXRhdGUocGFydHl0b3RhbD1uKCkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBncm91cF9ieShwaWQzLCBtYWlsKSAlPiUKICBtdXRhdGUocGFydHl2b3RldHlwZT1uKCkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUocGVyY2VudHBhcnR5dm90ZXR5cGU9cGVyY2VudChwYXJ0eXZvdGV0eXBlL3BhcnR5dG90YWwpKSAlPiUKICBncm91cF9ieShwaWQzLCBtYWlsKSAlPiUKICBmaWx0ZXIocm93X251bWJlcigpPT0xKSAlPiUKICBzZWxlY3QocGlkMyxtYWlsLCBwYXJ0eXRvdGFsLCBwYXJ0eXZvdGV0eXBlLCBwZXJjZW50cGFydHl2b3RldHlwZSkgJT4lCiAgZmlsdGVyKHBpZDM9PSJkZW1vY3JhdCAifHBpZDM9PSJyZXB1YmxpY2FuICIpICU+JQogIGZpbHRlcihtYWlsPT0xKSAlPiUKICBhcnJhbmdlKHBpZDMpCmFuYWx5c2lzMjAwODwtcmVuYW1lKGFuYWx5c2lzMjAwOCwgYygicGFydHkiPSJwaWQzIikpCmFuYWx5c2lzMjAwOCRZZWFyPC0yMDA4CmFuYWx5c2lzMjAwOCRwYXJ0eTwtYXMuY2hhcmFjdGVyKGFuYWx5c2lzMjAwOCRwYXJ0eSkKYW5hbHlzaXMyMDA4JHBhcnR5W2FuYWx5c2lzMjAwOCRwYXJ0eT09ImRlbW9jcmF0ICJdPC0iRGVtb2NyYXQiCmFuYWx5c2lzMjAwOCRwYXJ0eVthbmFseXNpczIwMDgkcGFydHk9PSJyZXB1YmxpY2FuICJdPC0iUmVwdWJsaWNhbiIKYW5hbHlzaXMyMDA4JHBhcnR5Y29sb3JbYW5hbHlzaXMyMDA4JHBhcnR5PT0iRGVtb2NyYXQiXTwtImJsdWUiCmFuYWx5c2lzMjAwOCRwYXJ0eWNvbG9yW2FuYWx5c2lzMjAwOCRwYXJ0eT09IlJlcHVibGljYW4iXTwtInJlZCIKYW5hbHlzaXMyMDA4CmBgYAoKQ29tYmluZSBkYXRhc2V0LgpgYGB7ciBjb21iaW5lIGFsbCB5ZWFycywgZWNobz1UUlVFLCBldmFsPVRSVUV9CmFuYWx5c2lzYnlwYXJ0eTwtcmJpbmQoYW5hbHlzaXMyMDIwLCBhbmFseXNpczIwMTYsIGFuYWx5c2lzMjAxMiwgYW5hbHlzaXMyMDA4KQphbmFseXNpc2J5cGFydHk8LXJlbmFtZShhbmFseXNpc2J5cGFydHksIGMoIlBlcmNlbnRhZ2UiPSJwZXJjZW50cGFydHl2b3RldHlwZSIpKQphbmFseXNpc2J5cGFydHkKYGBgCiMjIyBCeSBwYXJ0eSBtYWlsIGluIHZvdGluZyBpbiBlYWNoIGVsZWN0aW9uCgpgYGB7ciBvdmVyYWxsIHBsb3QgYnkgcGFydHksIGVjaG89VFJVRSwgZXZhbD1UUlVFLCBmaWcuYWxpZ249ImNlbnRlciJ9CmJ5cGFydHk8LWFuYWx5c2lzYnlwYXJ0eSAlPiUKICBnZ3Bsb3QoLixhZXMoeD1ZZWFyLHk9UGVyY2VudGFnZSwgZ3JvdXA9cGFydHkpKSsKICB0aGVtZV9idygpKwogIGdlb21fbGluZShhZXMoY29sb3I9cGFydHkpKSsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1wYXJ0eSkpKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiRGVtb2NyYXQiPSJibHVlIiwgIlJlcHVibGljYW4iPSJyZWQiKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJyaWdodCIpKwogIGFubm90YXRlKCJ0ZXh0IiwgeD0yMDE4LCB5PTAuNTUsIGxhYmVsPSJEZW1vY3JhdGljIFBhcnR5IiwgY29sb3I9ImJsdWUiKSsKICBhbm5vdGF0ZSgidGV4dCIsIHg9MjAxOSwgeT0wLjM1LCBsYWJlbD0iUmVwdWJsaWNhbiBQYXJ0eSIsIGNvbG9yPSJyZWQiKSsKICBsYWJzKHg9IlllYXIgb2YgRWxlY3Rpb24iLCB5PSJQZXJjZW50YWdlIG9mIE1haWwtaW4gVm90aW5nIiwgdGl0bGU9IlBlcmNlbnRhZ2Ugb2YgTWFpbC1pbiBWb3RpbmcgYnkgUGFydHkiKSsKICBzY2FsZV9zaXplX2NvbnRpbnVvdXMoZ3VpZGU9RkFMU0UpKwogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzPWMoMjAwOCwgMjAxMiwgMjAxNiwgMjAyMCkpKwogIHRoZW1lKHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYnlwYXJ0eQpgYGAKClRoZXJlIGlzIGFsc28gYSBzaGFycCBpbmNyZWFzZSBmcm9tIDIwMTYgdG8gMjAyMCBieSBwYXJ0eS4gUGFydGljdWxhcmx5LCBEZW1vY3JhdHMgZmF2b3IgdGhlIGlkZWEgb2YgbWFpbC1pbiB2b3RpbmcgbXVjaCBtb3JlIHRoYW4gUmVwdWJsaWNhbnMuCgojIyBQYXJ0IDIKCldl4oCZbGwgdGhlbiBleHBsb3JlIGlmIGRpZmZlcmVudCB2b3RpbmcgbWVjaGFuaXNtcyBjb3VsZCBoYXZlIGFuIGltcGFjdCBvbiBudW1iZXIgb2YgY2FzZXMuIEhvdyBkb2VzIHRoZSBwZXJjZW50YWdlIG9mIG1haWwtaW4gdm90aW5nIGFmZmVjdHMgdGhlIGluY3JlYXNlIG9mIENvdmlkLTE5IGNhc2VzPyBEbyBkZW1vY3JhdGljIHN0YXRlcyBhbmQgcmVwdWJsaWNhbiBzdGF0ZXMgZGlmZmVyIGluIHRoZSBpbmNyZWFzZSBvZiBDb3ZpZC0xOSBjYXNlcyBkdXJpbmcgdGhlIHdob2xlIHZvdGluZyBwZXJpb2QsIHNpbmNlIHRoZXkgbWlnaHQgaGF2ZSBkaWZmZXJlbnQgcG9saWNpZXMgYW5kIHByZWZlcmVuY2VzIHJlZ2FyZGluZyBpbiBwZXJzb24gdnMgbWFpbC1pbiB2b3RpbmcgYXQgc3RhdGUgZ292ZXJubWVudCBsZXZlbD8KCk9idGFpbiBsb25naXR1ZGUgYW5kIGxhdGl0dWRlIGRhdGEgb2YgVVMgc3RhdGVzLgpgYGB7ciB1cyBzdGF0ZXMsIGVjaG89VFJVRSwgZXZhbD1UUlVFfQp1cy5zdGF0ZXM8LW1hcF9kYXRhKCJzdGF0ZSIpCnVzLnN0YXRlczwtYXNfZGF0YV9mcmFtZSh1cy5zdGF0ZXMpCnVzLnN0YXRlczwtcmVuYW1lKHVzLnN0YXRlcywgYygic3RhdGUiPSJyZWdpb24iKSkKdXMuc3RhdGVzJHN1YnJlZ2lvbjwtTlVMTAp1cy5zdGF0ZXMkc3RhdGU8LXN0cl90b190aXRsZSh1cy5zdGF0ZXMkc3RhdGUpCiNBZGQgc3RhdGUgYWJicmV2aWF0aW9ucyBhbmQgY2VudGVycwpzdGF0ZW5hbWVzPC1hc19kYXRhX2ZyYW1lKGNiaW5kKHN0YXRlPXN0YXRlLm5hbWUsIHN0YXRlLmFiYj1zdGF0ZS5hYmIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlLmNlbnRlci54PXN0YXRlLmNlbnRlciR4LCBzdGF0ZS5jZW50ZXIueT1zdGF0ZS5jZW50ZXIkeSkpCnN0YXRlbmFtZXM8LXN0YXRlbmFtZXMgJT4lIAogIG11dGF0ZV9lYWNoXyhmdW5zKGFzLm51bWVyaWMpLCB2YXJzPWMoInN0YXRlLmNlbnRlci54Iiwic3RhdGUuY2VudGVyLnkiKSkKdXMuc3RhdGVzPC1sZWZ0X2pvaW4odXMuc3RhdGVzLCBzdGF0ZW5hbWVzKQp1cy5zdGF0ZXMKYGBgCgpGaW5kIGdlb2lkIGZvciBlYWNoIHVzIHN0YXRlcy4gUG9zc2libGUgcmVmZXJlbmNlIGxpbmsgY291bGQgYmUgKltramhlYWx5L2ZpcHMtY29kZXNdKGh0dHBzOi8vZ2l0aHViLmNvbS9ramhlYWx5L2ZpcHMtY29kZXMpKgpgYGB7ciBnZW9pZCwgZWNobz1UUlVFLCBldmFsPVRSVUV9Cmdlb2lkPC1yZWFkLmNzdigiL1VzZXJzL2FubmllL0RvY3VtZW50cy9HaXRIdWIvR3JvdXBfSF9FbGVjdGlvbl9Db3ZpZC9QZWlzaGFuX0xpL3N0YXRlX2ZpcHNfbWFzdGVyLmNzdiIpCmdlb2lkPC1yZW5hbWUoZ2VvaWQsIGMoInN0YXRlLmFiYiI9InN0YXRlX2FiYnIiKSkKZ2VvaWQ8LXJlbmFtZShnZW9pZCwgYygiR0VPSUQiPSJmaXBzIikpCmdlb2lkPC1nZW9pZCAlPiUKICBzZWxlY3Qoc3RhdGUuYWJiLCBHRU9JRCkKI0NvbnZlcnQgR0VPSUQgaW50byBjaGFyYWN0ZXJzCmdlb2lkJEdFT0lEPC1hcy5jaGFyYWN0ZXIoZ2VvaWQkR0VPSUQpCiNDZXJ0YWluIGZpcC1jb2RlcyBuZWVkIHRvIGJlIHByZS1wcm9jZXNzZWQKZ2VvaWQkR0VPSURbZ2VvaWQkc3RhdGUuYWJiPT0iQUwiXTwtIjAxIgpnZW9pZCRHRU9JRFtnZW9pZCRzdGF0ZS5hYmI9PSJBSyJdPC0iMDIiCmdlb2lkJEdFT0lEW2dlb2lkJHN0YXRlLmFiYj09IkFaIl08LSIwNCIKZ2VvaWQkR0VPSURbZ2VvaWQkc3RhdGUuYWJiPT0iQVIiXTwtIjA1IgpnZW9pZCRHRU9JRFtnZW9pZCRzdGF0ZS5hYmI9PSJDQSJdPC0iMDYiCmdlb2lkJEdFT0lEW2dlb2lkJHN0YXRlLmFiYj09IkNPIl08LSIwOCIKZ2VvaWQkR0VPSURbZ2VvaWQkc3RhdGUuYWJiPT0iQ1QiXTwtIjA5IgojQWRkIGZpcC1jb2RlcyBmb3IgRGlzdHJpY3Qgb2YgQ29sdW1iaWEKREM8LWMoIkRDIiwiMTEiKQpnZW9pZDwtcmJpbmQoZ2VvaWQsREMpCmdlb2lkCmBgYAoKQ29tYmluZSBzdGF0ZSBtYWlsIGRhdGFzZXQgd2l0aCBzdGF0ZSBhYmJyZXZpYXRpb25zLgpgYGB7ciBjb21iaW5lIHdpdGggYWJicmV2aWF0aW9ucywgZWNobz1UUlVFLCBldmFsPVRSVUV9CnVzZnVsbGFiYjwtdXMuc3RhdGVzICU+JQogIHNlbGVjdChzdGF0ZSwgc3RhdGUuYWJiKSAlPiUKICBncm91cF9ieShzdGF0ZSkgJT4lCiAgZmlsdGVyKHJvd19udW1iZXIoKT09MSkgJT4lCiAgdW5ncm91cCgpCmJ5c3RhdGVqb2luPC1sZWZ0X2pvaW4oYnlzdGF0ZSwgdXNmdWxsYWJiLCBieT0ic3RhdGUiKQojQSBmZXcgc3RhdGVzIG1pc3Mgc3RhdGUgYWJicmV2aWF0aW9ucy4gQ29tcGxldGUgdGhlIGxpc3QuCmJ5c3RhdGVqb2luJHN0YXRlLmFiYltieXN0YXRlam9pbiRzdGF0ZT09IkFsYXNrYSJdPSJBSyIKYnlzdGF0ZWpvaW4kc3RhdGUuYWJiW2J5c3RhdGVqb2luJHN0YXRlPT0iRGlzdHJpY3Qgb2YgQ29sdW1iaWEiXT0iREMiCmJ5c3RhdGVqb2luJHN0YXRlLmFiYltieXN0YXRlam9pbiRzdGF0ZT09Ikhhd2FpaSJdPSJISSIKYnlzdGF0ZWpvaW4KYGBgCgpDb21iaW5lIGRhdGFzZXQgZm9yIG51bWJlciBvZiBzdWNjZXNzZnVsIHByb2plY3RzIHdpdGggZ2VvaWQuCmBgYHtyIGNvbWJpbmUgYnlzdGF0ZSB3aXRoIGdlb2lkLCBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KYnlzdGF0ZWdlb2lkPC1sZWZ0X2pvaW4oYnlzdGF0ZWpvaW4sIGdlb2lkLCBieT0ic3RhdGUuYWJiIikKYnlzdGF0ZWdlb2lkCmBgYAoKT2J0YWluIHNoYXBlIGZpbGVzIG9mIFVTIHN0YXRlcyB1c2luZyB0aGUgYHRpZ3Jpc2AgcGFja2FnZS4KYGBge3Igc2hhcGVmaWxlcywgZWNobz1UUlVFLCBldmFsPVRSVUV9CnN0YXRlc2hhcGU8LXN0YXRlcyhjYj1UUlVFKQpgYGAKClJlYWQgaW4gY292aWQgY2FzZXMgZGF0YS4gKkRhdGEgc291cmNlIGlzIFtVbml0ZWQgU3RhdGVzIENEQ10oaHR0cHM6Ly9kYXRhLmNkYy5nb3YvQ2FzZS1TdXJ2ZWlsbGFuY2UvVW5pdGVkLVN0YXRlcy1DT1ZJRC0xOS1DYXNlcy1hbmQtRGVhdGhzLWJ5LVN0YXRlLW8vOW1mcS1jYjM2KSoKYGBge3IgY292aWQgZGF0YSwgZWNobz1UUlVFLCBldmFsPVRSVUV9CmNvdmlkPC1yZWFkLmNzdigiL1VzZXJzL2FubmllL0RvY3VtZW50cy9HaXRIdWIvR3JvdXBfSF9FbGVjdGlvbl9Db3ZpZC9QZWlzaGFuX0xpL1VuaXRlZF9TdGF0ZXNfQ09WSUQtMTlfQ2FzZXNfYW5kX0RlYXRoc19ieV9TdGF0ZV9vdmVyX1RpbWUuY3N2IikKYGBgCgpLZWVwIG9ubHkgZGF0YSBkdXJpbmcgdGhlIHZvdGluZyBwZXJpb2QuIFRoZSBlbGVjdGlvbiBkYXkgaXMgTm92ZW1iZXIgMywgYW5kIHRoZSBlYXJsaWVzdCB2b3RpbmcgdGltZSBpcyA0NiBkYXlzIGJlZm9yZSB0aGUgZWxlY3Rpb24gZGF5LiBSZWZlcmVuY2UgZnJvbSAqW0Vhcmx5IFZvdGluZyBDYWxlbmRhcl0oaHR0cHM6Ly93d3cudm90ZS5vcmcvZWFybHktdm90aW5nLWNhbGVuZGFyLykqLiBUaGUgZW5kIG9mIG91ciBvYnNlcnZhdGlvbiBkYXRlIGlzIDcgZGF5cyBhZnRlciB0aGUgZWxlY3Rpb24gZGF5LgpgYGB7ciBwcmVwcm9jZXNzaW5nLCBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KY292aWQkc3VibWlzc2lvbl9kYXRlPC1hcy5EYXRlKGNvdmlkJHN1Ym1pc3Npb25fZGF0ZSwgIiVtLyVkLyVZIikKI0ZpbHRlciBkYXRhIGR1cmluZyB0aGUgdm90aW5nIHBlaW9yZApjb3ZpZDwtY292aWQgJT4lCiAgYXJyYW5nZShzdWJtaXNzaW9uX2RhdGUpICU+JQogIGZpbHRlcihzdWJtaXNzaW9uX2RhdGU+PSIyMDIwLTA5LTE3IiAmc3VibWlzc2lvbl9kYXRlPD0iMjAyMC0xMS0xMCIpCiNHZW5lcmFsIHZpZXcKY292aWQ8LWNvdmlkICU+JQogIGdyb3VwX2J5KHN1Ym1pc3Npb25fZGF0ZSwgc3RhdGUpICU+JQogIG11dGF0ZShkYWlseXRvdGFsPXN1bSh0b3RfY2FzZXMpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZ3JvdXBfYnkoc3RhdGUpICU+JQogIG11dGF0ZShzdGF0ZXRvdGFsZHVyaW5ndm90aW5nPXN1bSh0b3RfY2FzZXMpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgc2VsZWN0KHN1Ym1pc3Npb25fZGF0ZSwgc3RhdGUsIHRvdF9jYXNlcywgZGFpbHl0b3RhbCwgc3RhdGV0b3RhbGR1cmluZ3ZvdGluZykKY292aWQ8LXJlbmFtZShjb3ZpZCwgInN0YXRlLmFiYiI9InN0YXRlIikKY292aWQKYGBgCgpUbyBtYWtlIHRoZSBudW1iZXIgb2YgY2FzZXMgY29tcGFyYWJsZSwgdGhleSBuZWVkIHRvIGJlIHdlaWdodGVkIGJ5IHN0YXRlIHBvcHVsYXRpb24uICpEYXRhIFNvdXJjZSBpcyBbVW5pdGVkIFN0YXRlcyBDZW5zdXMgQnVyZWF1XShodHRwczovL3d3dy5jZW5zdXMuZ292L3Byb2dyYW1zLXN1cnZleXMvcG9wZXN0L3RlY2huaWNhbC1kb2N1bWVudGF0aW9uL3Jlc2VhcmNoL2V2YWx1YXRpb24tZXN0aW1hdGVzLmh0bWwpKgoKYGBge3IgcG9wdWxhdGlvbiwgZWNobz1UUlVFLCBldmFsPVRSVUV9CnBvcHVsYXRpb248LXJlYWQuY3N2KCIvVXNlcnMvYW5uaWUvRG9jdW1lbnRzL0dpdEh1Yi9Hcm91cF9IX0VsZWN0aW9uX0NvdmlkL1BlaXNoYW5fTGkvbnN0LWVzdDIwMjAuY3N2IikKYGBgCgpLZWVwIG9ubHkgcG9wdWxhdGlvbiBlc3RpbWF0ZSBvZiAyMDIwIGFuZCBhdCBzdGF0ZSBsZXZlbC4KYGBge3IgcHJlcHJvY2VzcyBwb3B1bGF0aW9ucywgZWNobz1UUlVFLCBldmFsPVRSVUV9CnBvcHVsYXRpb248LXBvcHVsYXRpb24gJT4lCiAgc2VsZWN0KE5BTUUsIFBPUEVTVElNQVRFMjAyMCkgJT4lCiAgZmlsdGVyKE5BTUUhPSJVbml0ZWQgU3RhdGVzIiAmIE5BTUUhPSJOb3J0aGVhc3QgUmVnaW9uIiAmIE5BTUUhPSJNaWR3ZXN0IFJlZ2lvbiIgJiBOQU1FIT0iU291dGggUmVnaW9uIiAmIE5BTUUhPSJXZXN0IFJlZ2lvbiIpCnBvcHVsYXRpb248LXJlbmFtZShwb3B1bGF0aW9uLCBjKCJzdGF0ZSI9Ik5BTUUiKSkKcG9wdWxhdGlvbjwtcmVuYW1lKHBvcHVsYXRpb24sIGMoInBvcGVzdGltYXRlIj0iUE9QRVNUSU1BVEUyMDIwIikpCnBvcHVsYXRpb24KYGBgCgpDb21iaW5lIGNvdmlkIGRhdGFzZXQgd2l0aCBwb3B1bGF0aW9uIGRhdGFzZXQgYW5kIGNhbGN1bGF0ZSB0aGUgcGVyY2VudGFnZXMgb2YgY2FzZXMgd2l0aGluIHRoZSBzdGF0ZSBwb3B1bGF0aW9ucy4KYGBge3IgY29tYmluZSBjb3ZpZCBhbmQgcG9wdWxhdGlvbiBkYXRhc2V0LCBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KcG9wdWxhdGlvbjwtbGVmdF9qb2luKHBvcHVsYXRpb24sIHVzZnVsbGFiYiwgYnk9InN0YXRlIikKcG9wdWxhdGlvbiRzdGF0ZS5hYmJbcG9wdWxhdGlvbiRzdGF0ZT09IkFsYXNrYSJdPSJBSyIKcG9wdWxhdGlvbiRzdGF0ZS5hYmJbcG9wdWxhdGlvbiRzdGF0ZT09IkRpc3RyaWN0IG9mIENvbHVtYmlhIl09IkRDIgpwb3B1bGF0aW9uJHN0YXRlLmFiYltwb3B1bGF0aW9uJHN0YXRlPT0iSGF3YWlpIl09IkhJIgpwb3B1bGF0aW9uCmNvdmlkdzwtbGVmdF9qb2luKHBvcHVsYXRpb24sIGNvdmlkLCBieT0ic3RhdGUuYWJiIikKY292aWR3CmBgYAoKYGBge3Igd2VpZ2h0ZWQgZGF0YSwgZWNobz1UUlVFLCBldmFsPVRSVUV9CmNvdmlkdzwtY292aWR3ICU+JQogIGFycmFuZ2Uoc3VibWlzc2lvbl9kYXRlKSAlPiUKICBtdXRhdGUoZGFpbHl0b3RhbHc9cm91bmQoZGFpbHl0b3RhbC9wb3Blc3RpbWF0ZSoxMDAwMDAwKSkgJT4lCiAgbXV0YXRlKHN0YXRldG90YWx3PXJvdW5kKHN0YXRldG90YWxkdXJpbmd2b3RpbmcvcG9wZXN0aW1hdGUqMTAwMDAwMCkpCmNvdmlkdwpgYGAKClRvdGFsIG51bWJlciBpbiBlYWNoIHN0YXRlIHdlaWdodGVkCmBgYHtyIHRvdGFsIG51bWJlciwgZWNobz1UUlVFLCBldmFsPVRSVUV9CnRvdGFsY292aWQ8LWNvdmlkdyAlPiUKICBncm91cF9ieShzdGF0ZS5hYmIpICU+JQogIGZpbHRlcihyb3dfbnVtYmVyKCk9PTEpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBzZWxlY3Qoc3RhdGUsIHBvcGVzdGltYXRlLCBzdGF0ZS5hYmIsIHN0YXRldG90YWxkdXJpbmd2b3RpbmcsIHN0YXRldG90YWx3KQp0b3RhbGNvdmlkCnRvdGFsY292aWQ8LXJlbmFtZSh0b3RhbGNvdmlkLCBjKCJTVEFURSI9InN0YXRlIikpCmBgYAoKYGBge3IgYWxsIGRhdGEsIGVjaG89VFJVRSwgZXZhbD1UUlVFfQp0b3RhbGNvdmlkZ2VvaWQ8LWxlZnRfam9pbih0b3RhbGNvdmlkLCBnZW9pZCwgYnk9InN0YXRlLmFiYiIpCmFsbGRhdGE8LWxlZnRfam9pbih0b3RhbGNvdmlkZ2VvaWQsIGJ5c3RhdGVnZW9pZCwgYnk9IkdFT0lEIikKYWxsZGF0YSRzdGF0ZS5hYmIueTwtTlVMTAphbGxkYXRhJHN0YXRlPC1OVUxMCmFsbGRhdGE8LXJlbmFtZShhbGxkYXRhLCAic3RhdGUuYWJiIj0ic3RhdGUuYWJiLngiKQphbGxkYXRhJG1haWw8LWFzLm51bWVyaWMoYWxsZGF0YSRtYWlsKQphbGxkYXRhCmBgYAoKTWVyZ2Ugc3RhdGUgbWFwIGRhdGEgd2l0aCB3ZWlnaHRlZCBjb3ZpZCBjYXNlcy4KYGBge3IgbWVyZ2Ugc3RhdGUgZGF0YSB3aXRoIGNvdmlkLCBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KYWxsYnlzdGF0ZT1nZW9fam9pbihzdGF0ZXNoYXBlLCBhbGxkYXRhLCAiU1RBVEVGUCIsICJHRU9JRCIpCmFsbGJ5c3RhdGUKYGBgCgojIyMgTWFpbC1pbiB2b3RpbmcgcGVyY2VudGFnZSAmIHR5cGljYWwgRC9SIHN0YXRlIGludGVyYWN0aXZlIHBsb3QKClByb3ZpZGUgYSBsZWFmbGV0IG1hcCwgd2hlcmUgcG9seWdvbnMgYXJlIHVzZWQgdG8gcmVmbGVjdCB0aGUgcGVyY2VudGFnZSBvZiBtYWlsLWluIHZvdGluZy4gRWFjaCBzdGF0ZSBpcyBjYXRlZ29yaXplZCBhcyBhIHR5cGljYWwgRGVtb2NyYXRpYyBzdGF0ZSBvciBhIFJlcHVibGljYW4gc3RhdGUgYmFzZWQgb24gdGhlIHBlcmNlbnRhZ2Ugb2YgRGVtb2NyYXRzIGFuZCBSZXB1YmxpY2FucyBmcm9tIHRoZSAyMDIwIFNQQUUsIHdoaWNoIGlzIHJlcHJlc2VudGVkIGJ5IHRoZSBjb2xvciBvZiB0aGUgc3RhdGUncyBib3JkZXIgb24gdGhlIG1hcC4KYGBge3IgMXN0IG1hcCwgZWNobz1UUlVFLCBldmFsPVRSVUUsIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTd9CmNvbnRlbnQ8LXBhc3RlKCJTdGF0ZToiLCBhbGxieXN0YXRlJFNUQVRFLCAiPGJyLz4iLAogICAgICAgICAgICAgICAiVG90YWwgbnVtYmVyIG9mIGNhc2VzOiIsIGFsbGJ5c3RhdGUkc3RhdGV0b3RhbGR1cmluZ3ZvdGluZywgIjxici8+IiwKICAgICAgICAgICAgICAgIldlaWdodGVkIHRvdGFsIG51bWJlciBvZiBjYXNlczoiLCBhbGxieXN0YXRlJHN0YXRldG90YWx3LCAiPGJyLz4iLAogICAgICAgICAgICAgICJQZXJjZW50YWdlIG9mIG1haWwtaW4gdm90aW5nOiIsIGFsbGJ5c3RhdGUkbWFpbCwgIjxici8+IiwKICAgICAgICAgICAgICAiUGVyY2VudGFnZSBvZiBEZW1vY3JhdHMgaW4gQWxsIERlbW9jcmF0cyBhbmQgUmVwdWJsaWNhbnM6IiwgYWxsYnlzdGF0ZSREZW1vY3JhdHBlcmNlbnQsICI8YnIvPiIsCiAgICAgICAgICAgICAgIlBlcmNlbnRhZ2Ugb2YgUmVwdWJsaWNhbnMgaW4gQWxsIERlbW9jcmF0cyBhbmQgUmVwdWJsaWNhbnM6IiwgYWxsYnlzdGF0ZSRSZXB1YmxpY2FucGVyY2VudCwgIjxici8+IikKcGFsPWNvbG9yTnVtZXJpYyhwYWxldHRlPSJHcmVlbnMiLCBkb21haW49YWxsYnlzdGF0ZSRtYWlsKSAKbGVhZmxldG1hcDE8LWxlYWZsZXQoKSAlPiUKICBhZGRUaWxlcygpICU+JQogIGFkZFByb3ZpZGVyVGlsZXMoIlN0YW1lbi5Ub25lckxpdGUiKSAlPiUKICBzZXRWaWV3KC05OC4xMTU2LCAzOC40MjA0LCB6b29tPTQpICU+JQogIGFkZFBvbHlnb25zKGdyb3VwPSJNYWlsLWluIFZvdGluZyBQZXJjZW50YWdlIiwgZGF0YT1hbGxieXN0YXRlLCBmaWxsQ29sb3I9fnBhbChhbGxieXN0YXRlJG1haWwpLCBjb2xvcj1hbGxieXN0YXRlJHBhcnR5LCBmaWxsT3BhY2l0eT0wLjcsIHdlaWdodD0yLCBzbW9vdGhGYWN0b3I9MC4yLCBwb3B1cD1jb250ZW50LCBsYWJlbD1+c3RyaW5ncjo6c3RyX2MoTkFNRSwgJ1NlZSBwb3AtdXAgZm9yIG1vcmUgaW5mbycpLCBsYWJlbE9wdGlvbnM9bGFiZWxPcHRpb25zKGRpcmVjdGlvbj0nYXV0bycpLCBoaWdobGlnaHRPcHRpb25zPWhpZ2hsaWdodE9wdGlvbnMoY29sb3I9YWxsYnlzdGF0ZSRwYXJ0eSwgd2VpZ2h0PTUsIGJyaW5nVG9Gcm9udD1UUlVFLCBzZW5kVG9CYWNrPVRSVUUpKSAlPiUKICBhZGRMZWdlbmQoImJvdHRvbXJpZ2h0IiwgcGFsPXBhbCwgdmFsdWVzPWFsbGJ5c3RhdGUkbWFpbCwgdGl0bGU9IlN0YXRlIE1haWwtaW4gVm90aW5nIFBlcmNlbnRhZ2UiLCBvcGFjaXR5PTEpCmxlYWZsZXRtYXAxCmBgYAoKIyMjIFdlaWdodGVkIENvdmlkIGNhc2VzICYgdHlwaWNhbCBEL1Igc3RhdGUgaW50ZXJhY3RpdmUgcGxvdAoKUHJvdmlkZSBhIGxlYWZsZXQgbWFwLCB3aGVyZSBwb2x5Z29ucyBhcmUgdXNlZCB0byByZWZsZWN0IHRoZSBwZXJjZW50YWdlIG9mIGNvdmlkIGNhc2VzIGluY3JlYXNlIGluIHRoZSB2b3RpbmcgcGVyaW9kIHRpbGwgNyBkYXlzIGFmdGVyIGVsZWN0aW9uIGRheS4gRWFjaCBzdGF0ZSBpcyBjYXRlZ29yaXplZCBhcyBhIHR5cGljYWwgRGVtb2NyYXRpYyBzdGF0ZSBvciBhIFJlcHVibGljYW4gc3RhdGUgYmFzZWQgb24gdGhlIHBlcmNlbnRhZ2Ugb2YgRGVtb2NyYXRzIGFuZCBSZXB1YmxpY2FucyBmcm9tIHRoZSAyMDIwIFNQQUUsIHdoaWNoIGlzIHJlcHJlc2VudGVkIGJ5IHRoZSBjb2xvciBvZiB0aGUgc3RhdGUncyBib3JkZXIgb24gdGhlIG1hcC4KYGBge3IgMm5kIG1hcCwgZWNobz1UUlVFLCBldmFsPVRSVUUsIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTd9CmNvbnRlbnQ8LXBhc3RlKCJTdGF0ZToiLCBhbGxieXN0YXRlJFNUQVRFLCAiPGJyLz4iLAogICAgICAgICAgICAgICAiVG90YWwgbnVtYmVyIG9mIGNhc2VzOiIsIGFsbGJ5c3RhdGUkc3RhdGV0b3RhbGR1cmluZ3ZvdGluZywgIjxici8+IiwKICAgICAgICAgICAgICAgIldlaWdodGVkIHRvdGFsIG51bWJlciBvZiBjYXNlczoiLCBhbGxieXN0YXRlJHN0YXRldG90YWx3LCAiPGJyLz4iLAogICAgICAgICAgICAgICJQZXJjZW50YWdlIG9mIG1haWwtaW4gdm90aW5nOiIsIGFsbGJ5c3RhdGUkbWFpbCwgIjxici8+IiwKICAgICAgICAgICAgICAiUGVyY2VudGFnZSBvZiBEZW1vY3JhdHMgaW4gQWxsIERlbW9jcmF0cyBhbmQgUmVwdWJsaWNhbnM6IiwgYWxsYnlzdGF0ZSREZW1vY3JhdHBlcmNlbnQsICI8YnIvPiIsCiAgICAgICAgICAgICAgIlBlcmNlbnRhZ2Ugb2YgUmVwdWJsaWNhbnMgaW4gQWxsIERlbW9jcmF0cyBhbmQgUmVwdWJsaWNhbnM6IiwgYWxsYnlzdGF0ZSRSZXB1YmxpY2FucGVyY2VudCwgIjxici8+IikKcGFsPWNvbG9yTnVtZXJpYyhwYWxldHRlPSJPcmFuZ2VzIiwgZG9tYWluPWFsbGJ5c3RhdGUkc3RhdGV0b3RhbHcpIApsZWFmbGV0bWFwMjwtbGVhZmxldCgpICU+JQogIGFkZFRpbGVzKCkgJT4lCiAgYWRkUHJvdmlkZXJUaWxlcygiU3RhbWVuLlRvbmVyTGl0ZSIpICU+JQogIHNldFZpZXcoLTk4LjExNTYsIDM4LjQyMDQsIHpvb209NCkgJT4lCiAgYWRkUG9seWdvbnMoZGF0YT1hbGxieXN0YXRlLCBmaWxsQ29sb3I9fnBhbChhbGxieXN0YXRlJHN0YXRldG90YWx3KSwgY29sb3I9YWxsYnlzdGF0ZSRwYXJ0eSwgZmlsbE9wYWNpdHk9MC43LCB3ZWlnaHQ9Miwgc21vb3RoRmFjdG9yPTAuMiwgcG9wdXA9Y29udGVudCwgbGFiZWw9fnN0cmluZ3I6OnN0cl9jKE5BTUUsICcgU2VlIHBvcC11cCBmb3IgbW9yZSBpbmZvJyksIGxhYmVsT3B0aW9ucz1sYWJlbE9wdGlvbnMoZGlyZWN0aW9uPSdhdXRvJyksIGhpZ2hsaWdodE9wdGlvbnM9aGlnaGxpZ2h0T3B0aW9ucyhjb2xvcj1hbGxieXN0YXRlJHBhcnR5LCB3ZWlnaHQ9NSwgYnJpbmdUb0Zyb250PVRSVUUsIHNlbmRUb0JhY2s9VFJVRSkpICU+JQogIGFkZExlZ2VuZCgiYm90dG9tcmlnaHQiLCBwYWw9cGFsLCB2YWx1ZXM9YWxsYnlzdGF0ZSRzdGF0ZXRvdGFsdywgdGl0bGU9IlN0YXRlIFdlaWdodGVkIENvdmlkIENhc2VzIEluY3JlYXNlIER1cmluZyBWb3RpbmcgUGVyaW9kIiwgb3BhY2l0eT0xKQpsZWFmbGV0bWFwMgpgYGAKClJ1biBhIHJlZ3Jlc3Npb24gdG8gc2VlIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBtYWlsLWluIHZvdGluZyBwZXJjZW50YWdlIGFuZCB3ZWlnaHRlZCBjb3ZpZCBjYXNlcyBhbmQgdmlzdWFsaXplIHRoZSByZWxhdGlvbnNoaXAuCgpgYGB7ciByZWdyZXNzaW9uLCBlY2hvPVRSVUUsIGV2YWw9VFJVRX0KbG08LWxtKGxvZyhzdGF0ZXRvdGFsdyl+bWFpbCwgZGF0YT1hbGxkYXRhKQpzdW1tYXJ5KGxtKQpgYGAKClRoZSByZXN1bHQgc3VnZ2VzdHMgdGhhdCBvbiBhdmVyYWdlLCAxIHBlcmNlbnQgaW5jcmVhc2UgaW4gbWFpbC1pbiB2b3RpbmcgcHJvcG9ydGlvbiBsZWFkcyB0byBhIDY5LjQgcGVyY2VudCBkZWNyZWFzZSBvZiB3ZWlnaHRlZCBjb3ZpZCBjYXNlcyBpbiBhIHN0YXRlLCBub3QgdGFraW5nIGludG8gb3RoZXIgZmFjdG9ycyBpbnRvIGFjY291bnQsIGFuZCB0aGUgaW5mbHVlbmNlIGlzIHNpZ25pZmljYW50LgoKUGxvdCB0aGUgcmVsYXRpb25zaGlwIGdyb3VwZWQgYnkgRGVtb2NyYXRpYyBhbmQgUmVwdWJsaWNhbiBzdGF0ZXMuCmBgYHtyIHBsb3QgcmVsYXRpb25zaGlwLCBlY2hvPVRSVUUsIGV2YWw9VFJVRSwgZmlnLmFsaWduPSJjZW50ZXIifQphbGxkYXRhJHBhcnR5bmFtZVthbGxkYXRhJHBhcnR5PT0iYmx1ZSJdPC0iRGVtb2NyYXQiCmFsbGRhdGEkcGFydHluYW1lW2FsbGRhdGEkcGFydHk9PSJyZWQiXTwtIlJlcHVibGljYW4iCnJlbGF0aW9uc2hpcDwtZ2dwbG90KGFsbGRhdGEsIGFlcyh4PW1haWwsIHk9bG9nKHN0YXRldG90YWx3KSwgZ3JvdXA9cGFydHluYW1lKSkrCiAgdGhlbWVfYncoKSsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1wYXJ0eW5hbWUpKSsKICBnZW9tX3Ntb290aChhZXMoY29sb3I9cGFydHluYW1lKSxtZXRob2Q9ImxtIiwgZm9ybXVsYT15fngsIHNlPUZBTFNFKSsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoIkRlbW9jcmF0Ij0iYmx1ZSIsICJSZXB1YmxpY2FuIj0icmVkIikpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0icmlnaHQiKSsKICBsYWJzKHg9IlBlcmNlbnRhZ2Ugb2YgbWFpbC1pbiB2b3RpbmciLCB5PSJUb3RhbCBjb3ZpZCBjYXNlcyBpbiBhIHN0YXRlICh0YWtlbiBsb2dhcml0aG0pIiwgdGl0bGU9IlJlbGF0aW9uc2hpcCBiZXR3ZWVuIG1haWwtaW4gdm90aW5nIGFuZCBjb3ZpZCBjYXNlcyBpbmNyZWFzZSIpKwogIHRoZW1lKHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGhqdXN0PTAuNSkpCnJlbGF0aW9uc2hpcApgYGAKCgo=